﻿
namespace Kindohm.KSynth.Library
{
    public class Envelope : AttenuatorBase
    {
        uint counter = 0;
        uint attack;
        uint decay;
        double attackSlope = 0;
        double decaySlope = 0;
        const int MinAttenuation = 50;

        public Envelope()
        {
            this.Attack = 0;
            this.Sustain = uint.MaxValue;
            this.Decay = 0;
        }

        public uint Attack
        {
            get { return this.attack; }
            set
            {
                this.attack = value;
                this.attackSlope = MinAttenuation / (double)this.attack;
            }
        }

        public uint Decay
        {
            get { return this.decay; }
            set
            {
                this.decay = value;
                this.decaySlope = -MinAttenuation / (double)
                    ((this.decay + this.Sustain + this.attack) - (this.attack + this.Sustain));
            }
        }

        public uint Sustain { get; set; }

        public void Reset()
        {
            counter = 0;
        }

        public StereoSample ProcessSample(StereoSample sample)
        {
            counter++;

            if (counter < this.Attack)
            {
                return this.ProcessAttack(sample);
            }
            else if (counter > (this.Attack + this.Sustain))
            {
                return this.ProcessRelease(sample);
            }
            return sample;
        }

        StereoSample ProcessAttack(StereoSample sample)
        {
            //y = mx + b
            this.Attenuation = (int)((double)counter * this.attackSlope) - MinAttenuation;
            return this.Attenuate(sample);
        }

        StereoSample ProcessRelease(StereoSample sample)
        {
            //y = mx + b
            this.Attenuation = (int)((double)(counter - (this.attack + this.Sustain)) * this.decaySlope);
            return this.Attenuate(sample);
        }
    }
}
